package com.ljx.itbbs.server.user.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.ljx.itbbs.common.constant.CacheConstants;
import com.ljx.itbbs.common.domain.entity.UserEntity;
import com.ljx.itbbs.common.domain.vo.resp.PageResp;
import com.ljx.itbbs.common.manager.AsyncManager;
import com.ljx.itbbs.common.utils.RedisUtil;
import com.ljx.itbbs.common.utils.SecurityUtil;
import com.ljx.itbbs.server.article.domain.enums.GradeEnum;
import com.ljx.itbbs.server.article.service.PlateService;
import com.ljx.itbbs.server.user.dao.UserDao;
import com.ljx.itbbs.server.user.domain.enums.RoleEnum;
import com.ljx.itbbs.server.user.domain.vo.req.PlaterSettingReq;
import com.ljx.itbbs.server.user.domain.vo.req.UserPageReq;
import com.ljx.itbbs.server.user.domain.vo.req.UserUpdateReq;
import com.ljx.itbbs.server.user.domain.vo.resp.admin.UserInfoAdminResp;
import com.ljx.itbbs.server.user.service.UserPlateRelationService;
import com.ljx.itbbs.server.user.service.UserRoleRelationService;
import com.ljx.itbbs.server.user.service.UserService;
import com.ljx.itbbs.server.user.service.adapter.UserAdapter;
import com.ljx.itbbs.server.user.service.cache.UserCache;
import com.ljx.itbbs.server.user.service.handler.UserAsyncHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collections;
import java.util.List;
import java.util.Map;

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserDao userDao;

    @Autowired
    private UserRoleRelationService userRoleRelationService;

    @Autowired
    private UserCache userCache;

    @Autowired
    private UserPlateRelationService userPlateRelationService;

    @Override
    public UserEntity selectByUsername(String username) {
        return userDao.selectByUsername(username);
    }

    @Override
    public boolean checkUsernameUnique(String username) {
        return userDao.checkUsernameUnique(username);
    }

    @Override
    @Transactional
    public void registerUser(String username, String password) {
        // 保存账号
        UserEntity user = UserAdapter.buildRegisterUser(username, SecurityUtil.bCryptPassword(password));
        userDao.save(user);
        // 保存用户身份
        userRoleRelationService.save(user.getId(), RoleEnum.USER.getRoleId());
    }

    @Override
    public Map<Long, UserEntity> getUserInfoByIds(List<Long> ids) {
        return userCache.getBatch(ids);
    }

    @Override
    public UserEntity getUserInfoById(Long uid) {
        return this.getUserInfoByIds(Collections.singletonList(uid)).get(uid);
    }

    @Override
    public void updateUserInfo(Long uid, UserUpdateReq req) {
        // 修改数据库
        userDao.updateUserInfo(uid, req);
        delUserRedisCache(uid);
    }

    @Override
    public void delUserRedisCache(Long uid) {
        // 删除redis
        RedisUtil.del(CacheConstants.getKey(CacheConstants.USER_INFO, uid));
    }

    @Override
    public void increaseUserExp(Long userId, Long exp) {
        // 更新用户经验
        UserEntity userEntity = getUserInfoById(userId);
        userEntity.setExp(userEntity.getExp() + exp);
        userEntity.setGrade(GradeEnum.getGradeByExp(userEntity.getExp()).getGrade());
        userDao.updateById(userEntity);

        // 删除用户缓存
        delUserRedisCache(userId);
    }

    @Override
    public void increaseUserIntegral(Long userId, Integer integral) {
        userDao.increaseUserIntegral(userId, integral);

        // 删除用户缓存
        delUserRedisCache(userId);
    }

    @Override
    public PageResp<UserInfoAdminResp> adminUserList(UserPageReq req) {
        IPage<UserEntity> page = userDao.getUserPage(req);
        List<UserInfoAdminResp> records = BeanUtil.copyToList(page.getRecords(), UserInfoAdminResp.class);

        return PageResp.<UserInfoAdminResp>builder()
                .list(records)
                .total(page.getTotal())
                .build();
    }

    @Override
    public void adminUpdateUserStatus(Long userId, Integer status) {
        userDao.updateUserStatus(userId, status);
    }

    @Override
    @Transactional
    public void adminSettingPlater(PlaterSettingReq req) {
        // 保存对应关系
        userPlateRelationService.save(req.getPlateId(), req.getUid());
        // 异步更新板块中的版主记录
        AsyncManager.me().execute(UserAsyncHandler.updatePlateList(req.getUid(), req.getPlateId()));
    }

    @Override
    public void adminCancelPlater(PlaterSettingReq req) {
        // 删除对应关系
        userPlateRelationService.delete(req.getPlateId(), req.getUid());
        // 异步更新板块中的版主记录
        AsyncManager.me().execute(UserAsyncHandler.cancelPlater(req.getUid(), req.getPlateId()));
    }
}
